//
//  main.cpp
//  OpenGL
//
//  Created by xiaoxi on 2020/5/26.
//  Copyright © 2020 xiaoxi. All rights reserved.
//
//#include <GL/glew.h>
#include <GL/freeglut.h>
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#endif
#include "Graphics2DPrimitive.h"
#include <stdlib.h>
#include <iostream>
#include <vector>


void InitScreen();
void keyInput(unsigned char key,int x,int y);
void Display();
void Resize(int p_width,int p_height);
void animate(int someValue);

static bool isWire = true;  //是否为线框模式
static unsigned int VBO[2];    //VBO数组

int main(int argc,char** argv)
{
    srand(0);
    glutInit(&argc, argv);
    glutInitContextVersion(3, 3);
    glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);  //初始化深度缓冲区
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Create Window in MAC");
    glutDisplayFunc(Display);
    glutReshapeFunc(Resize);
    glutKeyboardFunc(keyInput);
    InitScreen();
    glutMainLoop();
}


void keyInput(unsigned char key,int x,int y)
{
    switch (key) {
       case 27:
            exit(0);
            break;
        case ' ':
            isWire = !isWire;
            glutPostRedisplay();
            break;
        default:
            break;
    }
}
static GeometryGenerator primitive;
void Display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清空颜色缓冲区和深度缓冲区
    if (isWire)
        glPolygonMode(GL_FRONT, GL_LINE);
    else
        glPolygonMode(GL_FRONT, GL_FILL);
    float* ptr = static_cast<float*>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));   //获取
    int index = 3;
    for(int i=0;i<primitive.vertex.size();i++)
    {
        ptr[index+i*6] = float(rand())/float(RAND_MAX);
        ptr[index+i*6+1] = float(rand())/float(RAND_MAX);
        ptr[index+i*6+2] = float(rand())/float(RAND_MAX);
    }
    glUnmapBufferARB(GL_ARRAY_BUFFER);
    glDrawElements(GL_TRIANGLES, static_cast<GLint>(primitive.index.size()), GL_UNSIGNED_INT, 0);
    glutSwapBuffers();
}

void Resize(int p_width,int p_height)
{
    glViewport(0, 0, p_width, p_height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //glOrtho(0.0, 100.0, 0.0, 100.0, -50.0, 50.0);
    glFrustum(-5.0, 5.0, -5.0, 5.0, 5.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void InitScreen()
{
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    //初始化图形信息
    primitive = Ellipse({0.0,0.0,-30.0}, 10.0, 15.0, 100, {0.2,0.6,0.4});
    //初始化VBO Handle
    glGenBuffers(2, VBO);
    //绑定顶点信息和VBO
    glBindBuffer(GL_ARRAY_BUFFER,VBO[0]);
    glBufferData(GL_ARRAY_BUFFER,sizeof(Vertex)*primitive.vertex.size(),NULL,GL_STATIC_DRAW);   //将VBO Handle和buffer绑定并为buffer分配空间
    glBufferSubData(GL_ARRAY_BUFFER,0,sizeof(Vertex)*primitive.vertex.size(),&primitive.vertex[0]); //将顶点数据传递到buffer中
    //绑定顶点索引和VBO
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,VBO[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(int)*primitive.index.size(),&primitive.index[0],GL_STATIC_DRAW);
    //使顶点和颜色生效
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    //指定颜色和顶点的位置信息
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0);
    glColorPointer(3, GL_FLOAT, sizeof(Vertex), (void*)(sizeof(VEC3)));
    glutTimerFunc(5, animate, 1);
}
void animate(int someValue)
{
    glutPostRedisplay();
    glutTimerFunc(500, animate, 1);
}
